﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using CaiyinSoft.NetGather.Protocol;

namespace CaiyinSoft.NetGather.NetGatherLib.Analyzer
{

    [Serializable]
    public class HTMLAnalyzerBase : IHTMLAnalyzer
    {


        public Dictionary<int, int> HTMLLineInfo{get;private set;}

        /// <summary>
        /// 当前HTML的页数
        /// </summary>
        public int PageIndex { get; set; }
        /// <summary>
        /// 待转换的HTML
        /// </summary>
        private string _InputHTML;
        public void SetInputHTML(string html)
        {
            _InputHTML = html;

            if (HTMLFilters != null)
            {
                foreach (IHTMLFilter filter in HTMLFilters)
                {
                    filter.SetInputHTML(html);
                }
            }

            if (NextHTMLFilter!=null)
                NextHTMLFilter.SetInputHTML(html);

            //HTMLLineInfo = new Dictionary<int, int>();
            //int line = 0;
            //System.IO.StringReader sr = new System.IO.StringReader(html);
            //while (sr.Peek()>0)
            //{
            //    line++;
            //    HTMLLineInfo.Add(line, sr.ReadLine().Length);
            //}
            //sr.Close();
        }
        public string GetInputHTML()
        {
            return _InputHTML;
        }

        [NonSerialized]
        private string _thisPageUrl = "";
        public void SetInputHTMLUrl(string url)
        {
            _thisPageUrl = url;
        }
        public string GetInputHTMLUrl()
        {
            return _thisPageUrl;
        }

        /// <summary>
        /// 转换完成后，保存的完整文件名
        /// </summary>
        //public string TargetFile { get; set; }

        public List<IHTMLFilter> HTMLFilters { get; set; }
        public IHTMLFilter _nextHTMLFilter;
        public IHTMLFilter NextHTMLFilter
        {
            get
            {
                return _nextHTMLFilter;
            }
            set
            {
                _nextHTMLFilter = value;
                _nextHTMLFilter.HTMLAnalyzer = this;
            }
        }

        public HTMLAnalyzerBase()
        {
            HTMLFilters = new List<IHTMLFilter>();
        }

        public virtual void AddFilter(IHTMLFilter htmlFilter)
        {
            htmlFilter.HTMLAnalyzer = this;
            HTMLFilters.Add(htmlFilter);
        }

        public virtual IHTMLFilter GetFilter(string outputKey)
        {
            return HTMLFilters.Find((e) => e.OutputKey.CompareTo(outputKey) == 0);
        }


        private List<IHTMLFilter> _convertResult;
        private List<IHTMLFilter> _nextHTMLResult;
        public virtual List<IHTMLFilter> Convert()
        {
            _convertResult = new List<IHTMLFilter>();
            foreach (IHTMLFilter filter in HTMLFilters)
            {
                filter.SetInputHTML( GetInputHTML());
            }

            foreach (IHTMLFilter filter in HTMLFilters)
            {
                _ConvertHTML(_convertResult, filter);
            }

            return _convertResult;
        }

        public virtual string NextPageUrl()
        {
            _nextHTMLResult = new List<IHTMLFilter>();
            if (NextHTMLFilter == null) return "";

            NextHTMLFilter.SetInputHTML ( GetInputHTML());
            _ConvertHTML(_nextHTMLResult, NextHTMLFilter);

            if (_nextHTMLResult.Count > 0 )
            {
                var fs= _nextHTMLResult[0].FilterHTML();
                if (fs != null && fs.Count > 0)
                {
                    System.Uri uri = null;
                    try
                    {
                        uri = new Uri(fs[0].HTMLResult);
                    }
                    catch
                    { }

                    if (uri == null) return "";
                    string page = uri.Segments[uri.Segments.Length - 1];
                    System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\w+\.\w+");
                    System.Text.RegularExpressions.Match match = regex.Match(page);
                    if (match.Success)
                        return fs[0].HTMLResult;
                    else
                        return "";
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }


        private void _ConvertHTML(List<IHTMLFilter> result, IHTMLFilter filter)
        {
            if (!filter.Runabled )
                return;            

            if (filter.ChildFilters != null && filter.ChildFilters.Count > 0)
            {
                foreach (IHTMLFilter t in filter.ChildFilters)
                {
                    if (t.Runabled )
                    {
                        _ConvertHTML(result, t);
                        if (t.RunOnce)
                            t.Runabled = false;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            else
            {
                result.Add(filter);
                if (filter.RunOnce)
                    filter.Runabled = false;
            }
        }

        //public int GetPosition(int line,int position)
        //{
        //    int revalue = 0;
        //    for (int i = 1; i < line; i++)
        //    {
        //        revalue += HTMLLineInfo[i];
        //    }
        //    return revalue + position;
        //}

        public IHTMLAnalyzer Clone()
        {
            HTMLAnalyzerBase analyzer = new HTMLAnalyzerBase();
            analyzer.PageIndex = 0;

            foreach (var filter in HTMLFilters)
            {
                analyzer.HTMLFilters.Add(filter.Clone());
            }

            return analyzer;
        }

        public virtual InnerFormBase GetEditForm()
        {
            return null;
        }

    }
}
